﻿/*************************************************************************************

- CLR版本：        4.0.30319.42000
- 类 名 称：       FlowHelper
- 机器名称：       YTE
- 命名空间：       LD.Host
- 文 件 名：       FlowHelper
- 创建时间：       2022/6/11 15:51:20
- 作    者：       YTE
- 说   明：
- 修改时间：
- 修 改 人：
  *************************************************************************************/

using Apache.NMS;
using LD.Tool;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace LD.Host
{
    public class FlowHelper
    {
        public static List<FlowTaskEx> TaskExs = new List<FlowTaskEx>();
        private static object lockObj = new object();
        public static OpResult Execute(TB_Tool model)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            string msg = string.Empty;
            bool isSuccess = false;
            try
            {
                BaseTool tool;
                string _className = $"LD.Tool.{model.ClassName}";
                //缓存处理
                //if (CacheTool.ContainsKey(_className))
                //{
                //    tool = CacheTool[_className];
                //    tool.isSuccess = false;
                //}
                //else
                //{
                //    Type type = Type.GetType(_className);
                //    tool = (BaseTool)Activator.CreateInstance(type);
                //    //类库调用方式
                //    //var obj = Assembly.GetExecutingAssembly();
                //    //var assembly = Assembly.LoadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LD.Tool.dll"));
                //    //tool = (BaseTool)assembly.CreateInstance(_className, true);
                //    if (tool != null)
                //    {
                //        CacheTool.TryAdd(_className, tool);
                //    }
                //}
                Type type = Type.GetType(_className);
                if (type == null)
                {
                    Log4.Error("工具必须定义在LD.Tool中");
                }
                else
                {
                    tool = (BaseTool)Activator.CreateInstance(type);
                    if (tool != null)
                    {
                        var result = tool.Execute(model);

                        tool.GetFlowResultField(model);

                        isSuccess = result.IsSuccess;
                        msg = result.Message;
                    }
                    else
                        msg = "工具实现方法查找失败";
                }

            }
            catch (Exception ex)
            {
                msg = "FlowHelper.Execute" + ex.Message;
                Log4.Error(ex);
            }
            finally
            {
                stopwatch.Stop();
            }
            return new OpResult() { IsSuccess = isSuccess, ExecuteTime = stopwatch.ElapsedMilliseconds, Message = msg };
        }
        public static FrmToolBase OpenFrmParam(TB_Tool model)
        {
            Type type = Type.GetType("LD.Tool." + model.FrmParam);
            if (type != null)
            {
                var frmBase = (FrmToolBase)Activator.CreateInstance(type);
                return frmBase;
            }
            return null;
            //var obj = Assembly.GetExecutingAssembly();
            //var assembly = Assembly.LoadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LD.Tool.dll"));
            //var frm = (FrmToolBase)assembly.CreateInstance($"LD.Tool.{ model.FrmParam}", true);
            //return frm;
        }
        public static void RunTool(TB_Flow flow)
        {
            foreach (var item in flow.Tools)
            {
                var opResult = Execute(item);
                if (!opResult.IsSuccess)
                    return;
            }
        }
        public static void RunFlow(string flowName)
        {
            var flow = Appbus.PartNo.Config.Flow.Where(p => p.Name == flowName).FirstOrDefault();
            if (flow == null)
                return;
            RunTool(flow);
        }
        public static void StartAll()
        {
            TaskExs = new List<FlowTaskEx>();

            var toolList = Appbus.PartNo.Config.Flow
                            .Where(p => p.FlowType == 0)
                            .OrderBy(p => p.Sort).ToList();

            if (toolList.Count > 0)
            {
                Appbus.StateEnum = StateEnum.自动模式;
                foreach (var item in toolList)
                {
                    Add(item);
                }
            }
        }
        public static Task Add(TB_Flow flow, bool runOne = false)
        {
            try
            {
                //判定流程线程是否有此”流程“
                if (!TaskExs.Where(p => p.Name == flow.Name).Any())
                {
                    FlowTaskEx taskEx = new FlowTaskEx();
                    var result = taskEx.Start(flow, runOne);
                    TaskExs.Add(taskEx);
                    if (runOne)
                    {
                        result.Wait();
                        TaskExs.Remove(taskEx);
                    }
                    return result;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                Log4.Log.Error(ex);
            }
            return null;
        }
        public static void Stop(TB_Flow flow)
        {
            if (TaskExs.Where(p => p.Name == flow.Name).Any())
            {
                var ts = TaskExs.Where(p => p.Name == flow.Name).FirstOrDefault();
                ts?.Pause();
                ts?.Cancel();
                TaskExs.Remove(ts);
            }
        }
        public static void StopAll()
        {
            Log4.Info($"全部任务停止");

            var temp = new FlowTaskEx[TaskExs.Count];
            TaskExs.CopyTo(temp);
            foreach (var item in temp)
            {
                Task.Run(() =>
                {
                    item?.Pause();
                    item?.Cancel();
                });
            }
            TaskExs?.Clear();

            //停止光栅
            if ((bool)Cache.GetCache(CONST.BC))
                LightStopHelper.Instance?.Stop();
        }
    }
}
